#ifndef __C_FS_DENTRY_H__
#define __C_FS_DENTRY_H__

#include "std/list.h"
#include "std/avltree.h"
#include "arch/atomic.h"

#ifdef __cplusplus
extern "C" {
#endif

struct inode;
struct dentry;
typedef unsigned char uchar;

typedef struct qstr
{
	uint size;
	uint hash;
	const uchar* str;
}
qstr_t;

typedef struct dentry_operations
{
	uint (*hash)(struct dentry*, qstr_t*);
	int (*compare)(struct dentry*, qstr_t*);
}
dentry_operations_t;

#define DENTRY_SMALL_NAME_LEN	(16)

/* Name hashing routines. Initial hash value */
#define init_name_hash()		0

/* partial hash update function. Assume roughly 4 bits per character */
static inline uint partial_name_hash(uint c, uint prevhash)
{
	prevhash = (prevhash << 4)
		| (prevhash >> (8 * sizeof(uint) - 4));
	return prevhash ^ c;
}

/* Finally: cut down the number of bits to a int value (and try to avoid losing bits) */
static inline uint end_name_hash(uint hash)
{
	if (sizeof(hash) > sizeof(uint))
		hash += hash >> 4 * sizeof(hash);
	return (uint) hash;
}

/* Compute the hash for a name string. */
static inline uint full_name_hash(const uchar * name, uint len)
{
	uint hash = init_name_hash();
	while (len--)
		hash = partial_name_hash(*name++, hash);
	return end_name_hash(hash);
}

typedef struct dentry
{
	listnode_t		child;
	listnode_t		hash;
	listnode_t		children;
	struct dentry*	parents;

	atomic_t		refcnt;
	uint			flags;
	uchar*			name;
	dentry_operations_t* ops;
	uchar			small_name[DENTRY_SMALL_NAME_LEN];
}
dentry_t;

// allocate a dentry
dentry_t* dalloc(qstr_t* name, dentry_operations_t* ops);

// global initialization
void global_init_vfs_namei_module(void);

#ifdef __cplusplus
}
#endif
#endif
/* EOF */
